/**
 * A prismatic joint. This joint provides one degree of freedom: translation
 * along an axis fixed in bodyA. Relative rotation is prevented. You can
 * use a joint limit to restrict the range of motion and a joint motor to
 * drive the motion or to model joint friction.
**/
public class b2PrismaticJoint extends b2Joint {
	public b2PrismaticJoint(int addr) {
		super(addr);
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			super.release();
		}
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorA() {
		return new b2Vec2(jni_GetAnchorA(address));
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorB() {
		return new b2Vec2(jni_GetAnchorB(address));
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jni_GetReactionForce(address, inv_dt));
	}

	public float GetReactionTorque(float inv_dt) {
		return jni_GetReactionTorque(address, inv_dt);
	}

	/// The local anchor point relative to bodyA's origin.
	public b2Vec2 GetLocalAnchorA() {
		return new b2Vec2(jni_GetLocalAnchorA(address));
	}

	/// The local anchor point relative to bodyB's origin.
	public b2Vec2 GetLocalAnchorB() {
		return new b2Vec2(jni_GetLocalAnchorB(address));
	}

	/// The local joint axis relative to bodyA.
	public b2Vec2 GetLocalAxisA() {
		return new b2Vec2(jni_GetLocalAxisA(address));
	}

	/// Get the reference angle.
	public float GetReferenceAngle() {
		return jni_GetReferenceAngle(address);
	}

	/// Get the current joint translation, usually in meters.
	public float GetJointTranslation() {
		return jni_GetJointTranslation(address);
	}

	/// Get the current joint translation speed, usually in meters per second.
	public float GetJointSpeed() {
		return jni_GetJointSpeed(address);
	}

	/// Is the joint limit enabled?
	public boolean IsLimitEnabled() {
		return jni_IsLimitEnabled(address);
	}

	/// Enable/disable the joint limit.
	public void EnableLimit(boolean flag) {
		jni_EnableLimit(address, flag);
	}

	/// Get the lower joint limit, usually in meters.
	public float GetLowerLimit() {
		return jni_GetLowerLimit(address);
	}

	/// Get the upper joint limit, usually in meters.
	public float GetUpperLimit() {
		return jni_GetUpperLimit(address);
	}

	/// Set the joint limits, usually in meters.
	public void SetLimits(float lower, float upper) {
		jni_SetLimits(address, lower, upper);
	}

	/// Is the joint motor enabled?
	public boolean IsMotorEnabled() {
		return jni_IsMotorEnabled(address);
	}

	/// Enable/disable the joint motor.
	public void EnableMotor(boolean flag) {
		jni_EnableMotor(address, flag);
	}

	/// Set the motor speed, usually in meters per second.
	public void SetMotorSpeed(float speed) {
		jni_SetMotorSpeed(address, speed);
	}

	/// Get the motor speed, usually in meters per second.
	public float GetMotorSpeed() {
		return jni_GetMotorSpeed(address);
	}

	/// Set the maximum motor force, usually in N.
	public void SetMaxMotorForce(float force) {
		jni_SetMaxMotorForce(address, force);
	}

	public float GetMaxMotorForce() {
		return jni_GetMaxMotorForce(address);
	}

	/// Get the current motor force given the inverse time step, usually in N.
	public float GetMotorForce(float inv_dt){
		return jni_GetMotorForce(address, inv_dt);
	}

	/// Dump to b2Log
	public void Dump() {
		throw new UnsupportedOperationException();
	}

	private static native int jni_GetLocalAxisA(int me);
	private static native int jni_GetLocalAnchorA(int me);
	private static native int jni_GetLocalAnchorB(int me);
	private static native float jni_GetReactionTorque(int me, float inv_dt);
	private static native int jni_GetReactionForce(int me, float inv_dt);
	private static native int jni_GetAnchorA(int me);
	private static native int jni_GetAnchorB(int me);
	private static native float jni_GetReferenceAngle(int me);
	private static native float jni_GetJointTranslation(int me);
	private static native float jni_GetJointSpeed(int me);
	private static native boolean jni_IsLimitEnabled(int me);
	private static native void jni_EnableLimit(int me, boolean flag);
	private static native float jni_GetLowerLimit(int me);
	private static native float jni_GetUpperLimit(int me);
	private static native void jni_SetLimits(int me, float lower, float upper);
	private static native void jni_EnableMotor(int me, boolean flag);
	private static native boolean jni_IsMotorEnabled(int me);
	private static native void jni_SetMotorSpeed(int me, float speed);
	private static native float jni_GetMotorSpeed(int me);
	private static native void jni_SetMaxMotorForce(int me, float force);
	private static native float jni_GetMaxMotorForce(int me);
	private static native float jni_GetMotorForce(int me, float inv_dt);
}
